package de.ryancarmon.validator.validators;

import de.ryancarmon.validator.P;
import de.ryancarmon.validator.ValidatorParam;
import de.ryancarmon.validator.exc.UnsupportedValidationException;
import de.ryancarmon.validator.exc.ValidationException;

public final class StringValidator extends BaseValidator<String> {

	protected void executeValidation(String param, ValidatorParam validation) {
		switch (validation) {
		case NOT_NULL:
			validateNotNull(param);
			break;
		case NOT_EMPTY:
			validateNotEmpty(param, false);
			break;
		case NOT_EMPTY_TRIM:
			validateNotEmpty(param, true);
			break;
		default:
			throw new UnsupportedValidationException(validation);
		}
	}

	protected void executeValidation(String param, ValidatorParam validation,
			Object validParam) {
		switch (validation) {
		case EQUALS:
			validateEquals(param, validParam, false);
			break;
		case EQUALS_NOCASE:
			validateEquals(param, validParam, true);
			break;
		case MIN_LENGTH:
			validateMinLength(param, validParam, false);
			break;
		case MIN_LENGTH_TRIM:
			validateMinLength(param, validParam, true);
			break;
		case MAX_LENGTH:
			validateMaxLength(param, validParam, false);
			break;
		case MAX_LENGTH_TRIM:
			validateMaxLength(param, validParam, true);
			break;
		default:
			throw new UnsupportedValidationException(validation);
		}
	}

	private void validateNotNull(String param) {
		if (param == null)
			throw new ValidationException(P.NOT_NULL, param);
	}

	private void validateNotEmpty(String param, boolean trim) {
		if (param == null)
			throw new IllegalArgumentException("'param' may not be null");

		String validate = (trim) ? param.trim() : param;

		if (validate.length() == 0)
			throw new ValidationException((trim) ? P.NOT_EMPTY_TRIM
					: P.NOT_EMPTY, param);
	}

	private void validateEquals(String param, Object equalsObj,
			boolean ignoreCase) {
		if (equalsObj == null && param == null)
			return;
		else if (param == null)
			throw new IllegalArgumentException("'param' may not be null");
		else if (equalsObj == null)
			throw new IllegalArgumentException("'equalsObj' may not be null");

		if (ignoreCase) {
			if (param.equalsIgnoreCase(toString(equalsObj)))
				return;
		} else {
			if (param.equals(equalsObj))
				return;
		}

		throw new ValidationException(
				(ignoreCase) ? P.EQUALS_NOCASE : P.EQUALS, equalsObj, param);
	}

	private void validateMinLength(String param, Object lengthObj, boolean trim) {
		if (param == null)
			throw new IllegalArgumentException("'param' may not be null");
		if (lengthObj == null)
			throw new IllegalArgumentException("'lengthObj' may not be null");

		int length = toInteger(lengthObj);
		String validate = (trim) ? param.trim() : param;

		if (length < 0)
			throw new IllegalArgumentException("'length' must be a positive value (greater 0)");

		if (validate.length() < length)
			throw new ValidationException((trim) ? P.MIN_LENGTH_TRIM
					: P.MIN_LENGTH, length, param);
	}

	private void validateMaxLength(String param, Object lengthObj, boolean trim) {
		if (param == null)
			throw new IllegalArgumentException("'param' may not be null");
		if (lengthObj == null)
			throw new IllegalArgumentException("'lengthObj' may not be null");

		int length = toInteger(lengthObj);
		String validate = (trim) ? param.trim() : param;

		if (length < 0)
			throw new IllegalArgumentException("'length' must be a positive value (greater 0)");

		if (validate.length() > length)
			throw new ValidationException((trim) ? P.MAX_LENGTH_TRIM
					: P.MAX_LENGTH, length, param);
	}
}
